import React from 'react'
import SearchHeader from '../../components/SearchHeader'
import { Flex, Icon, Toast } from 'antd-mobile' // flex组件
import { List , AutoSizer, WindowScroller, InfiniteLoader  } from 'react-virtualized' // 可视区域渲染插件
import getCurrentCity from '../../utils/currentCity'
import Filter from './components/Filter'
// CSS Modules 方式可以给我们组件内部的样式设置唯一的类名，样式隔离
import styles from './index.module.css'
import axios from 'axios'
import HouseItem from '../../components/HouseItem'
import Sticky from '../../components/Sticky'
import TideTitle from '../../components/TideTitle'


export default class HouseList extends React.Component {
  state = {
    city: '上海',
    cval:'', // 城市id
    QueryInfo: {}, // 请求参数
    list: [], // house数据集合
    count: 0 
  }
  async componentDidMount () {
    const cc = await getCurrentCity() // 获取现在城市数据
    this.setState(  _ => { // 默认地址
      return {
        city: cc.label,
        cval: cc.value
      }
    })
    this.searchHouseList() // 首次调用
  }
  onFilter = (QueryInfo)  => { // 接受filter组件发送过来的数据
    window.scroll(0,0) // 让页面回到0,0位置
   this.setState(_ => { // 保存到状态中
     return {
      QueryInfo: QueryInfo
     }
   }, _ => {
     this.searchHouseList()
   })
  }
  async searchHouseList () { // 获取房屋数据
    Toast.loading('数据加载中', 0)
    const { QueryInfo, cval } = this.state
    const params = {
      cityId: cval,
      start: 1,
      end: 20,
      ...QueryInfo
    }
    const { data:res } = await axios.get('http://api-haoke-web.itheima.net/houses', {params})
    this.setState(_ => {
      return {
        list: res.body.list,
        count: res.body.count
      }
    })
    Toast.hide() // 不行也行，Toast.info会替代loding,但是没有数据的时候Toast.info不会触发，以防万一
    if (res.body.count > 0) Toast.info(`共找到${res.body.count}房源信息`, 1.5)
    
  }
  houseListRender  = ( // 渲染List的每一项item项目
    { // react-virtualized组件渲染list方法
      index,       // 索引号
      style        // 重点属性：一定要给每一个行数添加该样式，将下方的list组件传的属性接收了
    }
  )  => { // 渲染下方房屋信息
    const { list } = this.state
    const house = list[index] // 这个方法会帮我们遍历数据，所以每一次我们就拿到数组里面当前的那个对象就行了
    // 有时候滑的很快下面的数据还没来得及获取，当前的house会取不到，因为Index超出数组长度，会报错
    if (!house) return (
      <div className={styles.zhan}></div>
    )
    return (
        <HouseItem
              // key={key}
              // style很关键，不传出问题
              // {pathname:'/demo', query:{id:22,name:'dahuang'}
              onClick={_ => this.props.history.push('/detail/' + house.houseCode)}
              // onClick={_ => this.props.history.push({pathname:'/detail', query:{id:22 }})}
              style={style}
              src={house.houseImg}
              title={house.title}
              desc={house.desc}
              tags={house.tags}
              price={house.price}
            />
      )
  }
  // 判断每一行数据是否加载完毕
  isRowLoaded = ({ index }) => {
    // console.log(index) // 看当前这个有没有数据
    return !!this.state.list[index]
  }

  // 用来获取更多房屋列表数据
  // 注意，该方法的返回值是一个 Promise 对象，并且，这个对象应该在数据加载完成时，来调用 resolve让 Promise对象的状态变为已完成
  loadMoreRows = ({ startIndex, stopIndex }) => { // 需要加载更多数据的方法,当前的数据块加载完的时候调用1
    const { QueryInfo, cval } = this.state
    return new Promise(resolve => {
      axios
        .get('http://api-haoke-web.itheima.net/houses', {
          params: {
            cityId: cval,
            start: startIndex,
            end: stopIndex,
            ...QueryInfo
          }
        })
        .then(res => {
          this.setState({
            list: [...this.state.list, ...res.data.body.list]
          })
          // 加载数据完成时，调用resolve即可
          resolve()
        })
    })
  }
  renderList = () => { // 条件渲染房屋信息
    const { count , list} = this.state
    if (list.length === 0) return '页面还在加载中'
    if (count === 0) return (<TideTitle/>)
    return (
      //  使用react这个插件可以让我们获取页面中属性，让list不在组件滚动 
      // 使用`WindowScroller`高阶组件，让List组件跟随页面滚动（为List组件提供状态，同时还需要设置List组件的autoHeight属性） 
      <InfiniteLoader // 做到了无限滚动列表
        isRowLoaded={this.isRowLoaded} // 每一行是否加载完
        loadMoreRows={this.loadMoreRows} // 每一行快加载完时触发，在这获取新数据
        rowCount={count}
      >
        {({ onRowsRendered, registerChild }) => (
      <WindowScroller> 
        {({ height, isScrolling, scrollTop }) => (
          // height 整个页面的视口高度
          // isScrolling 覆盖list自身的isScrolling属性，检测是否滚动
          // scrollTop 用来同步list中的滚动距离
          <AutoSizer> 
            {/* WindowScroller只能获取高度，宽度还得 AutoSizer来*/}
            {({ width }) => (
              <List // List组件只让组件自身出现滚动条，无法让整个页面滚动，也就无法实现标题吸顶功能
                autoHeight // 设置高度为 WindowScroller 最终渲染的列表高度
                ref={registerChild}
                // 组件的宽度
                width={width} // 视口宽度
                // 组件的高度
                height={height} // 视口高度 是单个高度乘以总数算来的
                rowCount={count} // List列表项总条目数
                // 每行的高度
                rowHeight={120} // 每一行高度
                rowRenderer={this.houseListRender}
                isScrolling={isScrolling}
                scrollTop={scrollTop}
                className={styles.zhan}
                onRowsRendered={onRowsRendered} //用InfiniteLoader高阶组件替换list原来绑定的监听刷新的事件
              />
            )}
          </AutoSizer>
        )}
    </WindowScroller> )}
       </InfiniteLoader>
    )
  }
  render() {
    return (
      <>
      {/* 上方搜索导航 */}
      <Flex className={styles.header}>
        <i className='iconfont icon-back' onClick={_ => {this.props.history.goBack()}}></i>
        <SearchHeader  city = {this.state.city} className={styles.seachHeader}/>
      </Flex>
      
      <Sticky>
        {/* prev筛选 */}
        <Filter onFilter={this.onFilter}/>
      </Sticky>


      {/* 房屋详情 */}
      {this.renderList()}
     
     </> 
    )
  }
}